/* $Id: array.c 17 2007-01-02 17:31:52Z judas $ */

#include <nih/cdefs.h>

#include <nih/array.h>

#include <errno.h>
#include <stdlib.h>

static int check_arg(const struct nih_array *array, size_t n);

struct nih_array *nih_acreate(size_t len)
{
        struct nih_array *array;

        array = calloc(1, sizeof(struct nih_array));
        if (array) {
                array->values = calloc(1, sizeof(void *) * len);

                if (array->values)
                        array->len = len;
                else {
                        free(array);
                        array = NULL;
                }
        }

        return array;
}

inline int check_arg(const struct nih_array *array, size_t n)
{
        int res;

        res = -1;

        if (!array)
                errno = EINVAL;
        else if (n >= array->len)
                errno = ERANGE;
        else
                res = 0;

        return res;
}

int nih_aset(struct nih_array *array, size_t n, const void *value)
{
        int res;

        res = -1;

        if (check_arg(array, n) == 0) {
                array->values[n] = (void *) value;
                res = 0;
        }

        return res;
}

int nih_aget(const struct nih_array *array, size_t n, void **value)
{
        int res;

        res = -1;

        if (value == NULL)
                errno = EINVAL;
        else if (check_arg(array, n) == 0) {
                *value = array->values[n];
                res = 0;
        }

        return res;
}

int nih_adestroy_deep(struct nih_array *array, nih_free_fnc *free_fnc)
{
        int res;

        res = -1;

        if (!array)
                errno = EINVAL;
        else {
                size_t i;

                for (i = 0; i < array->len; i++)
                        nih_free_call(free_fnc, array->values[i]);
                free(array->values);
                free(array);
                res = 0;
        }

        return res;
}

inline int nih_adestroy(struct nih_array *array)
{
        return nih_adestroy_deep(array, NULL);
}

